package com.zzj.ecology.admin.controller.system;

import com.zzj.ecology.admin.controller.BaseController;
import com.zzj.ecology.common.constant.UrlConstants;
import com.zzj.ecology.common.constant.UserConstant;
import com.zzj.ecology.common.enums.BusinessType;
import com.zzj.ecology.common.utils.StringUtils;
import com.zzj.ecology.framework.annotation.Log;
import com.zzj.ecology.framework.annotation.RepeatSubmit;
import com.zzj.ecology.system.bean.system.SysUser;
import com.zzj.ecology.system.domain.Page;
import com.zzj.ecology.system.dto.HttpResult;
import com.zzj.ecology.system.service.system.SysUserService;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.Date;
import java.util.List;

/**
 * https://blog.csdn.net/I_am_Hutengfei/article/details/100561564
 * https://www.cnblogs.com/softidea/p/6914279.html
 *
 * https://www.ctolib.com/mip/liuyatao-spring_security_verifycode.html
 * https://www.cnblogs.com/mujingyu/p/10702311.html
 *
 * https://www.cnblogs.com/hello-shf/p/10800457.html#_label3_3_1_6
 *
 *
 * DO（Data Object）：与数据库表结构一一对应，通过 DAO 层向上传输数据源对象。
 * DTO（Data Transfer Object）：数据传输对象，Service 和 Manager 向外传输的对象。
 * O（Business Object）：业务对象。可以由 Service 层输出的封装业务逻辑的对象。
 * Query：数据查询对象，各层接收上层的查询请求。注：超过 2 个参数的查询封装，禁止使用 Map 类来传输。
 * VO（View Object）：显示层对象，通常是 Web 向模板渲染引擎层传输的对象。
 */

@Slf4j
@Api(value = "SysUser",description = "SysUser登录用户相关操作接口")
@RestController
public class SysUserController extends BaseController {

    @Autowired
    private SysUserService sysUserService;

    /**
     * laytable 分页查询数据
     * @param page
     * @return
     */
    @ApiOperation(value = "分页查询", notes = "分页查询登录用户详细信息", httpMethod = "GET")
    @RequestMapping(value = UrlConstants.UserUrl.LIST)
    public HttpResult findPageList(@ApiParam Page page) {
        HttpResult result = sysUserService.findPageList(page);
        return success(result);
    }

    /**
     * 创建新用户
     * @param sysUser
     * @param bindingResult
     * @param userDetails
     * @return
     */
    @ApiOperation(value = "添加用户", notes = "新添加一个登录用户。 建立 用户与部门  用户与岗位 的关联关系", httpMethod = "POST")
    @RepeatSubmit
    @Log(title = "用户管理",businessType = BusinessType.INSERT)
    @PostMapping(value = UrlConstants.UserUrl.CREATE)
    public HttpResult create(@Valid SysUser sysUser, BindingResult bindingResult,
                             Integer postId, @AuthenticationPrincipal UserDetails userDetails) {
        sysUser.setCreateAt(new Date());
        sysUser.setCreateBy(userDetails.getUsername());
        sysUser.setPassword(getAuthInitializePassword());//设置初始密码
        HttpResult result = sysUserService.createAndBuildPostDeptRelation(sysUser, postId);
        return success(result);
    }

    /**
     * 检查登录用户是否存在
     * @param username
     * @return
     */
    @ApiImplicitParam(name = "username", value = "登录用户账号", required = true, dataType = "String")
    @ApiOperation(value = "查询账号是否存在", notes = "查询新增用户的账号是否存在,如果存在则不可使用。", httpMethod = "POST")
    @RequestMapping(value = UrlConstants.UserUrl.CHECK_USERNAME_EXIST)
    public boolean checkUsernameExist(String username) {
        return sysUserService.checkUsernameExist(username);
    }

    @ApiOperation(value = "批量删除用户", notes = "根据用户的ID或IDS, 删除用户。", httpMethod = "POST")
    @Log(title = "用户管理",businessType = BusinessType.DELETE)
    @PostMapping(value = UrlConstants.UserUrl.DELETE_BY_IDS)
    public HttpResult deleteByIds(@RequestParam("ids") List<Integer> userids) {
        //String username = SecurityUtils.getUsername();//((User) SecurityUtils.getPrincipal()).getUsername();
        if(userids.size() <= 0) return error();
        HttpResult result = sysUserService.updateDeleteStatusByIds(userids, getUsername());
        return success(result);
    }

    /**
     * 修改用户信息
     * @param sysUser
     * @return
     */
    @ApiOperation(value = "修改用户", notes = "修改登录用户的昵称、部门、用户类别、手机电话、备注等信息。并重新 建立 用户与部门  用户与岗位 的关联关系", httpMethod = "POST")
    @RepeatSubmit
    @Log(title = "用户管理",businessType = BusinessType.UPDATE)
    @PostMapping(value = UrlConstants.UserUrl.UPDATE)
    public HttpResult update(SysUser sysUser, Integer postId) {
        sysUser.setUpdateBy(getUsername());
        sysUser.setUpdateAt(new Date());
        HttpResult result = sysUserService.updateAndReBuildPostDeptRelation(sysUser, postId);
        return result;
    }

    /**
     * 接收前端页面的 用户ID 和 角色ID ST ,重新赋予用户角色 ,
     * 执行先删除 先前 user-role 的关联关系(不管角色delete_status='0'还是'1'), 然后重新赋予 新的 用户-角色 的权限关联关系
     * @param userId
     * @param roleIds
     * @return
     */
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户账号ID", required = true, dataType = "Integer"),
            @ApiImplicitParam(name = "roleIds", value = "角色ID数组", required = true, dataType = "Integer")
    })
    @ApiOperation(value = "重新授予角色权限",
            notes = "删除当前的用户角色的关联关系,再次建立新的用户角色关联关系。记录修改人员和修改时间。",
            httpMethod = "POST")
    @RepeatSubmit
    @Log(title = "用户管理",businessType = BusinessType.UPDATE)
    @PostMapping(value = UrlConstants.UserUrl.REGRANT_USER_ROLES)
    public HttpResult regrantUserRoles(@RequestParam(value = "userId", required = true) Integer userId,
                                       @RequestParam("roleIds") List<Integer> roleIds) {
        int i = sysUserService.regrantUserRolesByLoginUser(userId, roleIds, getUsername());
        return success();
    }

    /**
     * 初始化用户密码,记录修改人和修改时间
     * @param userId
     * @return
     */
    @ApiOperation(value = "初始化用户登录密码", notes = "管理员初始化用户登录密码的操作。", httpMethod = "POST")
    @RepeatSubmit
    @Log(title = "用户管理",businessType = BusinessType.UPDATE)
    @PostMapping(value = UrlConstants.UserUrl.INITIALIZE_PASSWORD)
    public HttpResult initializePassword(@ApiParam(value = "需要复位密码的用户ID") @RequestParam(value = "userId", required = true) Integer userId) {
        SysUser sysUser = new SysUser(userId, getUsername(), new Date());
        sysUser.setPassword(getAuthInitializePassword());
        int i = sysUserService.initializePassword(sysUser);
        return success();
    }

    /**
     * 启用 或停用 用户, 记录修改人和修改时间
     * @param userId
     * @return
     */
    @ApiOperation(value = "启用或者停用用户", notes = "停用或者启用某个用户的操作。", httpMethod = "POST")
    @RepeatSubmit
    @Log(title = "用户管理",businessType = BusinessType.UPDATE)
    @PostMapping(value = UrlConstants.UserUrl.UPDATE_USERSTATUS)
    public HttpResult startOrStopUser(@RequestParam(value = "userId", required = true) Integer userId) {
        SysUser sysUser = new SysUser(userId, getUsername(), new Date());
        //查询数据库, 根据数据库记录数据记录切换
        SysUser dbUser = sysUserService.findById(userId);
        if (StringUtils.equals(dbUser.getUserStatus(), UserConstant.USER_STATUS_START)) {
            sysUser.setUserStatus(UserConstant.USER_STATUS_STOP);
        } else {
            sysUser.setUserStatus(UserConstant.USER_STATUS_START);
        }
        sysUserService.updateUserStatus(sysUser);
        return success();
    }





}
